package com.netease.nim.uikit.api

import android.content.Context
import android.view.Gravity
import android.view.View
import com.lxj.xpopup.core.BasePopupView
import com.netease.nim.uikit.R
import com.netease.nim.uikit.api.model.main.OnlineStateContentProvider
import com.netease.nim.uikit.api.model.session.SessionCustomization
import com.netease.nim.uikit.api.model.session.SessionCustomization.OptionsButton
import com.netease.nim.uikit.api.model.session.SessionEventListener
import com.netease.nim.uikit.api.wrapper.NimMessageRevokeObserver
import com.netease.nim.uikit.business.ait.AitContactType
import com.netease.nim.uikit.business.session.module.MsgForwardFilter
import com.netease.nim.uikit.business.session.module.MsgRevokeFilter
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderTips
import com.netease.nim.uikit.business.team.helper.TeamHelper
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog
import com.netease.nim.uikit.impl.NimUIKitImpl.getRecentCustomization
import com.netease.nim.uikit.xpopup.CreateXPopupHelper
import com.netease.nim.uikit.xpopup.PopupViewEntity
import com.netease.nimlib.sdk.NIMClient
import com.netease.nimlib.sdk.RequestCallbackWrapper
import com.netease.nimlib.sdk.ResponseCode
import com.netease.nimlib.sdk.msg.MsgServiceObserve
import com.netease.nimlib.sdk.msg.attachment.AudioAttachment
import com.netease.nimlib.sdk.msg.attachment.ImageAttachment
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum
import com.netease.nimlib.sdk.msg.model.IMMessage
import com.netease.nimlib.sdk.robot.model.RobotAttachment
import com.netease.nimlib.sdk.team.model.TeamMember
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import www.wen.com.common.lib.app.BaseApplication
import www.wen.com.common.lib.data.entities.*
import www.wen.com.common.lib.extension.getString
import www.wen.com.common.lib.extension.postObject
import www.wen.com.common.lib.extension.toast
import www.wen.com.common.lib.helper.ResultUiCallBack
import www.wen.com.common.lib.helper.loading.KeyHelper
import java.util.*
import kotlin.collections.ArrayList


object SessionHelper {

    private var p2pCustomization: SessionCustomization? = null
    private var advancedTeamCustomization: SessionCustomization? = null

    var currentChannelVO: ServerGroupEntity.Content.ChannelVO? = null

    fun init() {
        // 设置会话中点击事件响应处理
        setSessionListener()
        // 注册消息转发过滤器
        registerMsgForwardFilter()
        // 注册消息撤回过滤器
        registerMsgRevokeFilter()
        // 注册消息撤回监听器
        registerMsgRevokeObserver()
        NimUIKit.setRecentCustomization(getRecentCustomization())
        NimUIKit.registerTipMsgViewHolder(MsgViewHolderTips::class.java)

        //设置在线状态文案提供者
        NimUIKit.setOnlineStateContentProvider(object : OnlineStateContentProvider {
            override fun getSimpleDisplay(account: String?): String =
                if (NIMHelper.allFriendsLoginStatus[account] == true)
                    NIMHelper.ONLINE_STATUS else NIMHelper.OFFLINE_STATUS

            override fun getDetailDisplay(account: String?): String =
                if (NIMHelper.allFriendsLoginStatus[account] == true)
                    NIMHelper.ONLINE_STATUS else NIMHelper.OFFLINE_STATUS
        })
    }

    fun startP2PSession(context: Context?, account: String, anchor: IMMessage? = null) {
//        currentChannelVO = null
        //清除未读数
        NIMHelper.updateP2pUnreadCount(account, 0)
        postObject(KeyHelper.UNREAD_COUNT_UPDATE, true)

        NimUIKit.setCommonP2PSessionCustomization(getP2pCustomization())
        NimUIKit.startP2PSession(context, account, anchor)
    }

    fun startTeamSession(
        context: Context?,
        tid: String,
        channelVO: ServerGroupEntity.Content.ChannelVO?,
        anchor: IMMessage? = NIMHelper.teamAitMessageMap[tid]?.lastOrNull()
    ) {
        currentChannelVO = channelVO
        //清除未读数
        NIMHelper.updateTeamUnreadCount(tid, 0)
        NIMHelper.updateTeamAitUnread(tid, hashSetOf())
        postObject(KeyHelper.UNREAD_COUNT_UPDATE, true)

        NimUIKit.setCommonTeamSessionCustomization(getTeamCustomization())
        NimUIKit.startTeamSession(context, tid, anchor)
    }

    /**
     * 定制化单聊界面。如果使用默认界面，返回null即可
     */
    private fun getP2pCustomization(): SessionCustomization? {
        if (p2pCustomization == null) {
            p2pCustomization = object : SessionCustomization() {}

            val optionsButtons = ArrayList<OptionsButton>()

            val option = object : SessionCustomization.OptionsButton() {
                override fun onClick(context: Context?, view: View?, sessionId: String?) {
                    if (context == null || sessionId.isNullOrEmpty()) {
                        toast(getString(R.string.get_team_failed))
                        return
                    }
                    val alertDialog = CustomAlertDialog(context)
                    prepareDialogItems(alertDialog, sessionId, true, context)
                    showBottomListDialog(alertDialog)
                }
            }
            option.iconId = R.drawable.ic_more_white
            optionsButtons.add(option)
            p2pCustomization!!.buttons = optionsButtons
        }

        return p2pCustomization
    }

    private fun prepareDialogItems(
        alertDialog: CustomAlertDialog,
        sessionId: String,
        canAddFriend: Boolean,
        context: Context?
    ) {
        alertDialog.addItem("清空聊天记录") {
            PopupViewEntity().let {
                it.context = context
                it.standardAlertPopupViewTitle = "确定清空聊天记录？"
                it.standardAlertPopupViewContent = "将会删除该条私信"
                it.standardAlertPopupViewCancelContent = "取消"
                it.standardAlertPopupViewConfirmContent = "关闭"
                it.finishOnCancel = true
                it.cancelFunction = { popupView ->
                    popupView.dismiss()
                }
                it.confirmFunction = { popupView ->
                    alertDialog.dismiss()
                    postObject(KeyHelper.CLOSE_SESSION_KEY, CloseSessionEntity())
                    popupView.dismiss()
                }
                it.isShow = true
                CreateXPopupHelper.createShowStandardAlertPopupView(it)
            }
        }

        //添加好友
        if (NIMHelper.isMyFriend(sessionId)) {
            alertDialog.addItem("删除好友", R.color.colorF04846) {
                PopupViewEntity().let {
                    it.context = context
                    it.standardAlertPopupViewTitle = "确定删除该用户？"
                    it.standardAlertPopupViewContent = "你与该好友的聊天记录不会删除"
                    it.standardAlertPopupViewCancelContent = "取消"
                    it.standardAlertPopupViewConfirmContent = "删除"
                    it.finishOnCancel = true
                    it.cancelFunction = { popupView ->
                        popupView.dismiss()
                    }
                    it.confirmFunction = { popupView ->
                        NIMHelper.deleteFriend(sessionId)
                        popupView.dismiss()
                    }
                    it.isShow = true
                    CreateXPopupHelper.createShowStandardAlertPopupView(it)
                }
            }
        } else {
            alertDialog.addItem("添加好友") {
                if (NIMHelper.isInBlackList(sessionId)) {
                    toast("你已屏蔽该用户,请先解除屏蔽")
                    return@addItem
                }
                if (!canAddFriend) {
                    toast("根据该用户的设定，你无法进行此操作")
                    return@addItem
                }
                toast(getString(R.string.add_success))
                NIMHelper.addFriend(sessionId)
            }
        }

        //屏蔽
        if (NIMHelper.isInBlackList(sessionId)) {
            alertDialog.addItem("解除屏蔽") {
                NIMHelper.removeFromBlackList(sessionId)
            }
        } else {
            alertDialog.addItem("屏蔽该好友", R.color.colorF04846) {
                PopupViewEntity().let {
                    it.context = context
                    it.standardAlertPopupViewTitle = "确定屏蔽该用户"
                    if (NIMHelper.isMyFriend(sessionId)) {
                        it.standardAlertPopupViewContent = "屏蔽此用户的同时将从你的好友列表中移除"
                    } else {
                        it.standardAlertPopupViewContent = "你将无法接收到该用户向你发出的私信"
                    }
                    it.standardAlertPopupViewCancelContent = "取消"
                    it.standardAlertPopupViewConfirmContent = "屏蔽"
                    it.finishOnCancel = true
                    it.cancelFunction = { popupView ->
                        popupView.dismiss()
                    }
                    it.confirmFunction = { popupView ->
                        NIMHelper.addToBlackList(sessionId)
                        popupView.dismiss()
                    }
                    it.isShow = true
                    CreateXPopupHelper.createShowStandardAlertPopupView(it)
                }
            }
        }

//        alertDialog.addItem("取消") {
//            alertDialog.dismiss()
//        }
    }

    /**
     * 定制化群聊界面。如果使用默认界面，返回null即可
     */
    private fun getTeamCustomization(): SessionCustomization? {
        if (advancedTeamCustomization == null) {
            advancedTeamCustomization = object : SessionCustomization() {}

            val optionsButtons = ArrayList<OptionsButton>()

            val option = object : SessionCustomization.OptionsButton() {
                override fun onClick(context: Context?, view: View?, sessionId: String?) {
                    if (context == null || sessionId.isNullOrEmpty()) {
                        toast(getString(R.string.get_team_failed))
                        return
                    }
                    // 跳转到设置页面
                    context.startActivity(
                        IntentFactory.obtainIMProxy(
                            sessionId,
                            currentChannelVO?.serverId
                        )
                    )
                }
            }
            option.iconId = R.drawable.ic_user_details_white
            optionsButtons.add(option)
            advancedTeamCustomization!!.buttons = optionsButtons
        }

        return advancedTeamCustomization
    }

    private fun setSessionListener() {
        val listener: SessionEventListener = object : SessionEventListener {
            override fun onAvatarClicked(context: Context?, message: IMMessage) {
                if (message.fromAccount == NIMHelper.getUserAccount()) {
                    context?.startActivity(IntentFactory.obtainMyPersonalHomepageFragmentIMProxy())
                }
                if (message.fromAccount == NIMHelper.getUserAccount()
                    || message.sessionType != SessionTypeEnum.Team
                ) {
                    return
                }

                val requestServersMemberList2 = BaseApplication.API.requestServersMemberList2(
                    currentChannelVO?.serverId ?: "",
                    TeamHelper.getTeamNick(message.sessionId, message.fromAccount),
                    0,
                    20
                )
                requestServersMemberList2.enqueue(object : Callback<ServiceMemberListEntity2> {
                    override fun onResponse(
                        call: Call<ServiceMemberListEntity2>,
                        response: Response<ServiceMemberListEntity2>
                    ) {
                        if (response.isSuccessful) {
                            val body = response.body()
                            val filter =
                                body?.data?.content?.filter { it.userId == message.fromAccount }
                            if (filter.isNullOrEmpty()) {
                                toast("该用户已退出服务器")
                            } else {
                                showBottomDialog(
                                    context,
                                    filter[0].userId,
                                    filter[0].allowFriendFlag == "1",
                                    filter[0].onlineStatus
                                ) { _, _, _ -> }
                            }
                        }
                    }

                    override fun onFailure(call: Call<ServiceMemberListEntity2>, t: Throwable) {
                        toast("请求用户资料失败，请稍后再试")
                    }
                })
            }

            override fun onAvatarLongClicked(context: Context?, message: IMMessage) {
                // 一般用于群组@功能，或者弹出菜单，做拉黑，加好友等功能
                if (message.fromAccount == NIMHelper.getUserAccount()) {
                    return
                }
                postObject(
                    KeyHelper.AIT_KEY,
                    AitEntity(
                        AitContactType.TEAM_MEMBER_WITH_AIT,
                        NIMHelper.getTeamMember(message.sessionId, message.fromAccount)
                    )
                )
            }

            override fun onAckMsgClicked(context: Context?, message: IMMessage?) {
                // 已读回执事件处理，用于群组的已读回执事件的响应，弹出消息已读详情
            }
        }
        NimUIKit.setSessionListener(listener)
    }

    /**
     * 消息转发过滤器
     */
    private fun registerMsgForwardFilter() {
        NimUIKit.setMsgForwardFilter(MsgForwardFilter { message ->
            if (message.msgType == MsgTypeEnum.custom &&
                message.attachment != null
            ) {
                // 白板消息和阅后即焚消息，红包消息 不允许转发
                return@MsgForwardFilter true
            } else if (message.msgType == MsgTypeEnum.robot && message.attachment != null // 如果是机器人发送的消息 不支持转发
                && (message.attachment as RobotAttachment).isRobotSend
            ) {
                return@MsgForwardFilter true
            }
            false
        })
    }

    /**
     * 消息撤回过滤器
     */
    private fun registerMsgRevokeFilter() {
        NimUIKit.setMsgRevokeFilter(MsgRevokeFilter { message ->
            if (message.attachment != null &&
                message.attachment !is ImageAttachment &&
                message.attachment !is AudioAttachment
            ) {
                // 视频通话消息和白板消息，红包消息 不允许撤回
                return@MsgRevokeFilter true
            }
            false
        })
    }

    /**
     * 消息撤回的观察者
     */
    private fun registerMsgRevokeObserver() {
        NIMClient.getService(MsgServiceObserve::class.java)
            .observeRevokeMessage(NimMessageRevokeObserver(), true)
    }

    fun showBottomDialog(
        context: Context?,
        account: String,
        canAddFriend: Boolean,
        onlineStatus: Boolean,
        action: (View, TeamMember, BasePopupView) -> Unit
    ) {
        PopupViewEntity().let {
            it.context = context
            it.userDetailIsMyFriend = NIMHelper.isMyFriend(account)
            it.userDetailUserInfo = NIMHelper.getTeamMember(currentChannelVO?.teamId ?: "", account)
            it.userDetailOnlineStatus = onlineStatus
            it.userDetailResultUiCallBack = object : ResultUiCallBack<TeamMember> {
                override fun invoke(view: View, result: TeamMember, popupView: BasePopupView) {
                    when (view.id) {
                        R.id.llOne -> {
                            //好友主页
//                            toast("好友主页")
                            // 跳转到设置页面
                            context?.startActivity(IntentFactory.obtainPersonalHomepageFragmentIMProxy(account))
                        }
                        R.id.llTwo -> {
                            //添加
                            postObject(
                                KeyHelper.AIT_KEY,
                                AitEntity(AitContactType.TEAM_MEMBER_WITH_AIT, result)
                            )
                            popupView.dismiss()
                        }
                        R.id.llThree -> {
                            if (NIMHelper.isMyFriend(account)) {
                                //私信
                                startP2PSession(context, account)
                                popupView.dismiss()
                            } else {
                                //添加好友
                                if (!canAddFriend) {
                                    toast("根据该用户的设定，你无法进行此操作")
                                    return
                                }
                                NIMHelper.addFriend(account, callback = object :
                                    RequestCallbackWrapper<Void?>() {
                                    override fun onResult(
                                        code: Int,
                                        result: Void?,
                                        exception: Throwable?
                                    ) {
                                        if (code != ResponseCode.RES_SUCCESS.toInt() || exception != null) {
                                            toast(getString(R.string.add_failed))
                                            return
                                        }
                                        toast(getString(R.string.add_success))
                                        popupView.dismiss()
                                    }
                                })
                            }
                        }
                        R.id.imgMore -> {
                            val alertDialog = CustomAlertDialog(context)
                            prepareDialogItems(alertDialog, account, canAddFriend, context)
                            showBottomListDialog(alertDialog)
                        }
                    }
                    action.invoke(view, result, popupView)
                }
            }
            it.isShow = true
            CreateXPopupHelper.createBottomUserDetailPopupView(it)
        }
    }

    /**
     * TODO 需要改为XPopup
     */
    private fun showBottomListDialog(alertDialog: CustomAlertDialog) {
        alertDialog.setCancelable(true)
        alertDialog.setCanceledOnTouchOutside(true)
        val window = alertDialog.window
        window?.setGravity(Gravity.BOTTOM)

        alertDialog.show()
    }

}